/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
 *
 */

import { remove } from '@baize/wdk';
import * as path from 'path';

import { ConfigJson } from '../../../../src/options/configure/config-json-options';
import { updateElementInArrayByUniqueKey } from '../common';

import { BaseModifier } from './base-modifier';
import AbilitiesObj = ConfigJson.AbilitiesObj;
import AppObj = ConfigJson.AppObj;
import ConfigOptObj = ConfigJson.ConfigOptObj;
import DeviceConfigObj = ConfigJson.DeviceConfigObj;
import DeviceConfigOptionObj = ConfigJson.DeviceConfigOptionObj;
import DistroObj = ConfigJson.DistroObj;
import JsObj = ConfigJson.JsObj;
import ModuleObj = ConfigJson.ModuleObj;

/**
 * 修改指定模块的config.json
 */
export class ConfigJsonModifier extends BaseModifier {
  protected jsonObject!: ConfigOptObj;

  constructor(cwd: string, moduleName: string, target = 'main') {
    super(path.resolve(cwd, moduleName, 'src', target, 'config.json'));
  }

  public setApp(app: AppObj) {
    this.jsonObject.app = app;
    return this;
  }

  public setDeviceConfig(deviceConfig: DeviceConfigObj) {
    this.jsonObject.deviceConfig = deviceConfig;
    return this;
  }

  public setDeviceType(deviceType: string[]) {
    this.jsonObject.module.deviceType = deviceType;
    return this;
  }

  public addDeviceConfigOption(key: string, deviceConfigObj: DeviceConfigOptionObj) {
    this.jsonObject.deviceConfig[key] = deviceConfigObj;
    return this;
  }

  public setModule(module: ModuleObj) {
    this.jsonObject.module = module;
    return this;
  }

  public updateModule(module: ModuleObj) {
    this.jsonObject.module = {
      ...this.jsonObject.module,
      ...module
    };
    return this;
  }

  public setDistro(distro: DistroObj) {
    this.jsonObject.module.distro = distro;
    return this;
  }

  public getAbilities(): AbilitiesObj[] | undefined {
    return this.jsonObject.module.abilities;
  }

  public getAbilityByName(name: string): AbilitiesObj | null {
    if (this.jsonObject.module.abilities !== undefined) {
      for (const ability of this.jsonObject.module.abilities) {
        if (ability.name === name) {
          return ability;
        }
      }
    }
    return null;
  }

  public updateAbility(ability: AbilitiesObj) {
    this.jsonObject.module.abilities = updateElementInArrayByUniqueKey(this.jsonObject.module.abilities, ability);
    return this;
  }

  public updateJs(js: JsObj) {
    this.jsonObject.module.js = updateElementInArrayByUniqueKey(this.jsonObject.module.js, js);
    return this;
  }

  public getJs(): JsObj[] | undefined {
    return this.jsonObject.module.js;
  }

  public getJsByName(name: string): JsObj | null {
    if (this.jsonObject.module.js !== undefined) {
      for (const js of this.jsonObject.module.js) {
        if (js.name === name) {
          return js;
        }
      }
    }
    return null;
  }

  /**
   * 根据name删除指定js配置
   *
   * @param {string} name
   */
  public rmJsByName(name: string): ConfigJsonModifier {
    const jsComponents = this.jsonObject.module.js;
    if (jsComponents === undefined) {
      return this;
    }

    remove(jsComponents, jsObj => {
      return jsObj.name === name;
    });
    return this;
  }

  /**
   * 根据name删除指定ability
   *
   * @param {string} name
   */
  public rmAbilityByName(name: string): ConfigJsonModifier {
    const abilities = this.getAbilities();
    if (abilities === undefined) {
      return this;
    }

    remove(abilities, abilityObj => {
      return abilityObj.name === name;
    });
    return this;
  }
}
